package tv.acgn.advertisement.search.index.impl;

import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import tv.acgn.advertisement.search.exception.AbstractAdSearchException;
import tv.acgn.advertisement.search.exception.AdPlanIoEmptyException;
import tv.acgn.advertisement.search.index.IndexAware;
import tv.acgn.advertisement.search.indexobejct.AdUnitIO;

/**
 * @author : junG
 * @program : advertisement-ad-search-index
 * @description : 推广单元索引操作实现类
 * @date : 2019-07-07 22:49
 **/
@Service
@Slf4j
public class AdUnitIndexImpl  implements IndexAware<String, AdUnitIO> {
    /**
     * 索引存储
     * TODO 后续换成redis存储
     */
    private static Map<String,AdUnitIO> indexMap=new ConcurrentHashMap<String,AdUnitIO>();

    /**
     * <h2>通过索引的键获取值</h2>
     *
     * @param key [1] 键
     *
     * @return {@link AdUnitIO} 值对象
     *
     * @throws AbstractAdSearchException 异常
     * @author junG
     * @description 通过索引的键获取值
     * @date 22:31 2019/6/30
     */
    @Override
    public AdUnitIO get(String key) throws AbstractAdSearchException {
        return Optional.ofNullable(indexMap.get(key))
            .orElseGet(AdUnitIO::emptyIO);
    }

    /**
     * <h2>新增一条索引</h2>
     *
     * @param key        [1] 键
     * @param adUnitIO [2] 值对象
     *
     * @return {@link Void}
     *
     * @throws AbstractAdSearchException 异常
     * @author junG
     * @description 新增一条索引
     * @date 22:32 2019/6/30
     */
    @Override
    public void add(String key, AdUnitIO adUnitIO) throws AbstractAdSearchException {
        log.debug("新增索引 新增前 推广计划索引对象 AdUnitIndexMap.keySet={}",indexMap.keySet());
        indexMap.put(key,adUnitIO);
        log.debug("新增索引 新增后 推广计划索引对象 AdUnitIndexMap.keySet={}",indexMap.keySet());
    }

    /**
     * <h2>更新索引键对应的索引值对象</h2>
     *
     * @param key        [1]
     * @param adUnitIO [2]
     *
     * @return {@link Void}
     *
     * @throws AbstractAdSearchException 异常
     * @author junG
     * @description 更新索引键对应的索引值对象
     * @date 22:35 2019/6/30
     */
    @Override
    @SuppressWarnings({"Duplicates"})
    public void update(String key, AdUnitIO adUnitIO) throws AbstractAdSearchException {
        Optional.ofNullable(adUnitIO)
            .orElseThrow(AdPlanIoEmptyException::new);

        log.debug("更新索引 更新前 推广单元索引对象 AdUnitIO={}",indexMap.get(key));
        AdUnitIO toUpdateIO= indexMap.get(key);
        if (null != toUpdateIO) {
            BeanUtils.copyProperties(adUnitIO,toUpdateIO);
            indexMap.put(key,toUpdateIO);
        }else {
            indexMap.put(key,adUnitIO);
        }

        log.debug("更新索引 更新后 推广单元索引对象 AdUnitIO={}",indexMap.get(key));
    }

    /**
     * <h2>删除索引对象</h2>
     *
     * @param key [1]
     *
     * @return {@link Void}
     *
     * @throws AbstractAdSearchException 异常
     * @author junG
     * @description 删除索引对象
     * @date 22:26 2019/6/30
     */
    @Override
    public void delete(String key) throws AbstractAdSearchException {
        indexMap.remove(key);
    }
}
